<template>
  <div class="app-container">

    <el-row :gutter="20">
      <!--分组数据-->
      <el-col :span="4" :xs="24">
        <div>
          <el-button type="primary" size="mini" @click="handleQueryAll">全部展示</el-button>
        </div>
        <div class="head-container" style="margin-top:5px">
          <el-input
              v-model="name"
              :placeholder="$t('equipment.groupingInput')"
              clearable
              size="small"
              prefix-icon="el-icon-search"
              style="margin-bottom: 20px"
          />
        </div>
        <div class="head-container tree">
          <el-tree
              ref="tree"
              :data="groupOptions"
              :props="defaultProps"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              :highlight-current="true"
              default-expand-all
              @node-click="handleNodeClick"
          >
            <div slot-scope="{ node, data }" class="el-tree-node__label custom-tree-node custom-tree-item"
                 style="position: relative;"
            >
              <span class="name">{{ data.name }}</span>
              <div class="right-btns" style="position: absolute;right: 0; top: 0; background: #F5F7FA; height: 100%"
                   @click.stop
              >
                <svg-icon v-hasPerm="['group_add']" icon-class="plus" @click="addGroup(node, data)"/>
                <svg-icon v-hasPerm="['group_edit']" icon-class="edit" @click="editGroup(node, data)"/>
                <svg-icon v-if="data.parentId > 0" v-hasPerm="['group_del']" icon-class="delete"
                          @click="deleteGroup(node, data)"
                />
              </div>
            </div>
          </el-tree>
        </div>
      </el-col>

      <!--模板数据-->
      <el-col :span="20" :xs="24">
        <el-form v-show="showSearch" ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
          <el-form-item :label="$t('material.templateName')" prop="name">
            <el-input
                v-model="queryParams.name"
                :placeholder="$t('material.templateNameInput')"
                clearable
                size="small"
                @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item :label="$t('program.status')" prop="status">
            <el-select v-model="queryParams.status" :placeholder="$t('equipment.statusSelect')" clearable size="small">
              <el-option
                  v-for="dict in statusOptions"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('elButton.establishTime')">
            <el-date-picker
                v-model="dateRange"
                size="small"
                style="width: 240px"
                value-format="yyyy-MM-dd"
                type="daterange"
                range-separator="-"
                :start-placeholder="$t('elButton.startTime')"
                :end-placeholder="$t('elButton.endTime')"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{
                $t('elButton.search')
              }}
            </el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ $t('elButton.reset') }}</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
                v-hasPerm="['template_add']"
                type="primary"
                icon="el-icon-plus"
                size="mini"
                @click="handleAdd"
            >{{ $t('elButton.add') }}
            </el-button>
          </el-col>
          <div class="top-right-btn">
            <el-tooltip class="item" effect="dark" :content="$t('elButton.refresh')" placement="top">
              <el-button size="mini" circle icon="el-icon-refresh" @click="handleQuery"/>
            </el-tooltip>
            <el-tooltip class="item" effect="dark"
                        :content="showSearch ? $t('elButton.hideSearch') : $t('elButton.showSearch')" placement="top"
            >
              <el-button size="mini" circle icon="el-icon-search" @click="showSearch=!showSearch"/>
            </el-tooltip>
          </div>
        </el-row>

        <!--循环-->
        <el-row v-loading="loading" class="program-container">
          <el-card v-for="it in programList" :key="it.id" class="box-card" shadow="hover"
                   :body-style="{ padding: '8px', position: 'relative' }"
          >
            <img :src="VUE_APP_BASE_API + it.cover" @click.native="handleClickEdit(it)">
            <div class="info" @click.native="handleClickEdit(it)">
              <div class="title">{{ it.name }} ({{ it.width }} * {{ it.height }})</div>
              <!--<div class="remarks">{{ it.remarks }}</div>-->
              <div class="create-time">{{ $t('equipment.createTime') }}：{{ it.createTime }}</div>
            </div>
            <div class="operation">
              <div v-if="checkPerm(['template_edit'])" class="edit" @click="handleClickEdit(it)">
                <el-tooltip effect="dark" placement="bottom" :content="$t('elButton.edit')">
                  <el-icon class="el-icon-edit"/>
                </el-tooltip>
              </div>
              <div v-if="checkPerm(['template_del'])" class="delete" @click="handleDel(it)">
                <el-tooltip effect="dark" :content="$t('elButton.delete')" placement="bottom">
                  <el-icon class="el-icon-delete"/>
                </el-tooltip>
              </div>
              <div v-if="checkPerm(['template_view'])" class="preview" @click="handleClickPreview(it)">
                <el-tooltip effect="dark" :content="$t('elButton.preview')" placement="bottom">
                  <el-icon class="el-icon-view"/>
                </el-tooltip>
              </div>
            </div>
          </el-card>
          <p v-if="total == 0" style="text-align: center;">{{ $t('elButton.noDataNow') }}</p>
        </el-row>

        <pagination
            v-show="total>0"
            :total="total"
            :page.sync="queryParams.current"
            :limit.sync="queryParams.size"
            @pagination="getList"
        />

      </el-col>

    </el-row>

    <!-- 添加或修改节目对话框 -->
    <el-dialog class="custom-dialog" :title="title" :visible.sync="open" :modal-append-to-body="true"
               :append-to-body="true" :close-on-click-modal="false" @closed="handleClosed"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-row>
          <!--分组-->
          <el-col :span="24">
            <el-form-item :label="$t('material.templateName')" prop="name">
              <el-input v-model="form.name" :placeholder="$t('material.templateNameInput')"/>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item :label="$t('equipment.sort')" prop="groupId">
              <treeselect @input="inputSelect"
                          v-model="form.groupId"
                          :options="groupOptions.length ? groupOptions[0].children : []"
                          :normalizer="normalizer"
                          :placeholder="$t('equipment.sortInput')"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item :label="$t('equipment.resolving')" prop="resolution">
              <el-select v-model="form.resolution" :placeholder="$t('equipment.resolvingInput')"
                         @change="handleResolutionChange"
              >
                <el-option v-for="it in resolutionList" :key="it" :label="it" :value="it"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col v-if="showCustomResolution" :span="12">
            <el-form-item :label="$t('program.width')" prop="customWidth">
              <el-input v-model="form.customWidth" type="number" :placeholder="$t('program.widthInput')"/>
            </el-form-item>
          </el-col>
          <el-col v-if="showCustomResolution" :span="12">
            <el-form-item :label="$t('program.height')" prop="customWidth">
              <el-input v-model="form.customHeight" type="number" :placeholder="$t('program.heightInput')"/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{ $t('submitText') }}</el-button>
        <el-button @click="cancel">{{ $t('cancelText') }}</el-button>
      </div>
    </el-dialog>

    <!--添加/编辑分组-->
    <el-dialog class="wrapper" :title="$t('material.sort')" :visible.sync="groupDialogVisible" width="30%"
               :close-on-click-modal="false" :modal-append-to-body="true" :append-to-body="true"
               @closed="groupDialogClosed"
    >
      <el-form @submit.native.prevent ref="form" :model="groupObj" :rules="groupRules" label-width="80px">
        <el-form-item :label="$t('equipment.sort')" prop="name">
          <el-input
              ref="name"
              v-model="groupObj.name"
              size="small"
              @keyup.enter.native="handleClickSaveGroup"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleClickSaveGroup">{{ $t('submitText') }}</el-button>
        <el-button @click="groupDialogVisible = false">{{ $t('cancelText') }}</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { listProgram, getProgram, delProgram, exportProgram } from '@/api/ips/program'
import { addGroup, delGroup, editGroup, groupTree } from '@/api/ips/group'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { getLabelByValInTree } from '@/utils/obj-util'
import { setKV } from '@/utils/storage-util'
import { checkPerm, checkRole } from '@/utils/permission' // 权限判断函数

export default {
  name: 'Template',
  components: { Treeselect },
  data() {
    const nameValidator = (rule, val, callback) => {
      if (val) {
        callback()
      } else {
        callback(new Error(this.$t('equipment.groupingInput')))
      }
    }
    const customWidthValidator = (rule, val, callback) => {
      if (this.showCustomResolution) {
        if (val) {
          callback()
        } else {
          callback(new Error(this.$t('program.widthInput')))
        }
      } else {
        callback()
      }
    }
    const customHeightValidator = (rule, val, callback) => {
      if (this.showCustomResolution) {
        if (val) {
          callback()
        } else {
          callback(new Error(this.$t('program.heightInput')))
        }
      } else {
        callback()
      }
    }
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 节目表格数据
      programList: [],
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 日期范围
      dateRange: [],
      // 是否模板字典
      isTemplateOptions: [], // 状态字典
      statusOptions: [], // 查询参数
      name: undefined,
      groupOptions: [],
      groupDict: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      queryParams: {
        current: 1,
        size: 10,
        fullPathId: 49,
        isTemplate: '1',
        name: undefined,
        status: undefined,
        createTime: undefined
      },
      // 显示搜索条件
      showSearch: true,
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        name: [
          { required: true, message: this.$t('material.templateNameEmpty'), trigger: 'change' }
        ],
        groupId: [
          { required: true, message: this.$t('equipment.sortEmpty'), trigger: 'blur' }
        ],
        resolution: [
          { required: true, message: this.$t('equipment.resolvingEmpty'), trigger: 'change' }
        ],
        customWidth: [{ validator: customWidthValidator }],
        customHeight: [{ validator: customHeightValidator }]
      },
      VUE_APP_BASE_API: process.env.VUE_APP_BASE_API,
      // 分组相关
      groupDialogVisible: false,
      groupObj: { name: undefined },
      groupRules: {
        name: [{ validator: nameValidator }]
      },
      // 分辨率
      resolutionList: [
        '1920*1080',
        '1080*1920',
        '1366*768',
        '2048*1080',
        '4096*3122',
        '自定义'
      ],
      // 是否显示自定义分辨率输入框
      showCustomResolution: false
    }
  },
  watch: {
    // 根据名称筛选分组名称树
    name(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    this.getList()
    this.getGroupTree()
    this.getDicts('yes_no').then(response => {
      this.isTemplateOptions = response.data
    })
    this.getDicts('status').then(response => {
      this.statusOptions = response.data
    })
  },
  methods: {
    checkPerm,
    checkRole,
    inputSelect() {
      this.$refs.form.validateField('groupId')
    },
    // 点击了模板
    handleClickEdit(it) {
      setKV('PREVIOUS_ROUTE', 'template')
      setKV('PROGRAM_INFO', JSON.stringify(it))
      this.$router.push('/editor')
    },
    // 预览
    handleClickPreview(it) {
      const programData = JSON.parse(it.layout)
      programData.sacle = 1.0
      this.$EventBus.$emit('PREVIEW', programData)
    },
    /** 查询节目列表 */
    getList() {
      this.loading = true
      listProgram(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
        this.programList = response.data
        this.total = response.total
        this.loading = false
      })
    },
    /** 转换机构数据结构 */
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.id,
        label: node.name,
        children: node.children
      }
    },
    /** 查询分组名称下拉树结构 */
    getGroupTree() {
      groupTree({ groupId: 49 }).then(response => {
        this.groupOptions = response.data
        this.groupDict = []
        const findChildren = (arr, list) => {
          for (let i = 0; i < arr.length; i++) {
            if (arr[i].id) {
              list.push(arr[i])
            }
            if (arr[i].children && arr[i].children.length) {
              findChildren(arr[i].children, list)
            }
          }
        }
        findChildren(this.groupOptions, this.groupDict)
      })
    },
    // 筛选节点
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    // 节点单击事件
    handleNodeClick(data) {
      this.queryParams.fullPathId = data.id
      // this.queryParams.current = 1
      this.getList()
    },
    // 是否模板字典翻译
    isTemplateFormat(row, column) {
      return this.selectDictLabel(this.isTemplateOptions, row.isTemplate)
    },
    // 状态字典翻译
    statusFormat(row, column) {
      return this.selectDictLabel(this.statusOptions, row.status)
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    // 表单重置
    reset() {
      this.form = {
        id: undefined,
        resolution: undefined,
        customWidth: undefined,
        customHeight: undefined,
        name: '模板-' + new Date().getTime(),
        groupId: undefined,
        groupName: undefined,
        cover: undefined,
        width: undefined,
        height: undefined,
        duration: undefined,
        layout: undefined,
        isTemplate: '1',
        status: undefined
      }
      this.resetForm('form')
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.current = 1
      this.getList()
    },
    handleQueryAll() {
      this.queryParams.fullPathId = ''
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = []
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = this.$t('material.addTemplate')
    },
    /** 修改按钮操作 */
    handleEdit(row) {
      this.reset()
      const id = row.id || this.ids
      getProgram(id).then(response => {
        this.form = response.data
        this.open = true
        this.title = this.$t('material.changeTemplate')
      })
    },
    /** 提交按钮 */
    submitForm: function() {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.form.groupName = getLabelByValInTree(this.groupDict, this.form.groupId, {
            label: 'name',
            value: 'id'
          })
          this.form.isTemplate = 1
          setKV('PREVIOUS_ROUTE', 'template')
          setKV('PROGRAM_INFO', JSON.stringify(this.form))
          this.$router.push('/editor')
        }
      })
    },
    /** 删除按钮操作 */
    handleDel(row) {
      const ids = row.id || this.ids
      this.$confirm(this.$t('material.deleteTemplateNumber') + ids + this.$t('equipment.deleteEquipment2'), this.$t('warning'), {
        confirmButtonText: this.$t('submitText'),
        cancelButtonText: this.$t('cancelText'),
        type: 'warning'
      }).then(function() {
        return delProgram(ids)
      }).then(() => {
        this.getList()
        this.msgSuccess(this.$t('deleteSuccess'))
      }).catch(function() {
      })
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams
      this.$confirm(this.$t('material.exportTemplate'), this.$t('warning'), {
        confirmButtonText: this.$t('submitText'),
        cancelButtonText: this.$t('cancelText'),
        type: 'warning'
      }).then(function() {
        return exportProgram(queryParams)
      }).then(response => {
        this.download(response.data)
      }).catch(function() {
      })
    },
    // 添加分组
    addGroup(node, data) {
      this.groupObj = {
        name: undefined,
        type: 'template',
        parentId: data.id
      }
      this.groupDialogVisible = true
    },
    // 编辑分组
    editGroup(node, data) {
      this.groupObj = JSON.parse(JSON.stringify(data))
      this.groupDialogVisible = true
    },
    // 删除分组
    deleteGroup(node, data) {
      this.$confirm(this.$t('material.deleteMaterialSort') + data.name + '?', this.$t('warning'), {
        confirmButtonText: this.$t('submitText'),
        cancelButtonText: this.$t('cancelText'),
        type: 'warning'
      }).then(function() {
        return delGroup(data.id)
      }).then(() => {
        this.getGroupTree()
        this.getList()
        this.msgSuccess(this.$t('deleteSuccess'))
      }).catch(function() {
      })
    },
    groupDialogClosed() {
      this.groupObj = { name: undefined }
    },
    handleClickSaveGroup() {
      this.$refs['form'].validate(valid => {
        if (valid) {
          const fun = this.groupObj.id ? editGroup : addGroup
          fun(this.groupObj)
              .then(_ => {
                this.getGroupTree()
                this.$message({
                  message: this.$t('saveSuccess'),
                  type: 'success',
                  showClose: true
                })
                this.groupDialogVisible = false
              })
              .catch(_ => {
              })
        }
      })
    },
    handleResolutionChange(val) {
      this.showCustomResolution = val === '自定义'
    },
    handleClosed() {
      this.showCustomResolution = false
    }
  }
}
</script>

<style lang="scss" scoped>
.tree {
  overflow-x: auto;
}

.el-tree {
  min-width: 100%;
  display: inline-block;
}

.program-container {
  &:after {
    content: "";
    display: block;
    clear: both;
  }

  .el-card {
    float: left;
    box-sizing: border-box;
    margin: 8px;
    cursor: pointer;
    width: 316px;
    height: 298px;

    img {
      width: 300px;
      height: 200px;
    }

    .info {
      .title {
        font-weight: 500;
        color: #0e1113;
        margin: 4px 0;
      }

      .remarks,
      .create-time {
        color: #8c92a4;
        font-size: 14px;
        margin: 2px 0;
      }
    }

    .operation {
      &:after {
        content: "";
        display: block;
        clear: both;
      }

      padding: 8px 8px;

      > div {
        float: left;
        width: 33.33333%;
        text-align: center;
        box-sizing: border-box;
        transition: .1s all;

        &:not(:nth-of-type(3)) {
          border-right: 1px solid #ccc;
        }

        &:hover {
          color: #1890ff;
        }
      }
    }
  }

  .add-program {
    position: relative;
    user-select: none;

    h2 {
      position: absolute;
      margin: 0;
      font-size: 60px;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
    }
  }
}

.app-container {
  .custom-tree-item {
    &:after {
      content: "";
      display: block;
      clear: both;
    }

    &:hover {
      .right-btns {
        opacity: 1;
      }
    }

    font-size: 16px;
    width: 100%;

    .right-btns {
      float: right;
      color: #000;
      opacity: 0;
      transition: .3s all;
      user-select: none;

      .svg-icon {
        margin: 0 2px;

        &:hover {
          color: #999;
        }
      }
    }
  }

  .custom-dialog {
    .el-select {
      width: 100%;
    }
  }
}
</style>
